package ifrn.scartissue.server;

import ifrn.scartissue.common.utils.Validator;

import java.sql.SQLException;
import java.util.List;

import marauroa.common.crypto.Hash;
import marauroa.common.game.AccountResult;
import marauroa.common.game.CharacterResult;
import marauroa.common.game.RPAction;
import marauroa.common.game.RPObject;
import marauroa.common.game.RPObjectInvalidException;
import marauroa.common.game.RPObjectNotFoundException;
import marauroa.common.game.Result;
import marauroa.server.db.DBTransaction;
import marauroa.server.db.TransactionPool;
import marauroa.server.game.db.AccountDAO;
import marauroa.server.game.db.CharacterDAO;
import marauroa.server.game.db.DAORegister;
import marauroa.server.game.rp.IRPRuleProcessor;
import marauroa.server.game.rp.RPServerManager;

public class RuleProcessor implements IRPRuleProcessor {
	
	private static RuleProcessor instance;
	private World world = World.get();
	private RPServerManager manager;
	
	public static RuleProcessor get() {
		if (instance == null) {
			instance = new RuleProcessor();
		}
		return instance;
	}

	@Override
	public void beginTurn() {
	}

	@Override
	public boolean checkGameVersion(String game, String version) {
		return true;
	}

	@Override
	public AccountResult createAccount(String username, String password, String email) {
		
		if (username.isEmpty() || password.isEmpty() || email.isEmpty()) {
			return new AccountResult(Result.FAILED_EMPTY_STRING, username);
		}
		
		if (!Validator.validEmail(email)) {
			return new AccountResult(Result.FAILED_EXCEPTION, username);
		}
		
		TransactionPool transactionPool = TransactionPool.get();
		DBTransaction trans = transactionPool.beginWork();
		AccountDAO accountDAO = DAORegister.get().get(AccountDAO.class);
		
		try {
			if (accountDAO.hasPlayer(trans, username)) {
				return new AccountResult(Result.FAILED_PLAYER_EXISTS, username);
			}
			accountDAO.addPlayer(trans, username, Hash.hash(password), email);
			transactionPool.commit(trans);
			return new AccountResult(Result.OK_CREATED, username);
		} catch (SQLException e) {
			transactionPool.rollback(trans);
			return new AccountResult(Result.FAILED_EXCEPTION, username);
		}
	}

	@Override
	public CharacterResult createCharacter(String username, String characterName,
			RPObject template) {
		TransactionPool transactionPool = TransactionPool.get();
		DBTransaction trans = transactionPool.beginWork();
		CharacterDAO characterDAO = DAORegister.get().get(CharacterDAO.class);
		try {
			if (characterDAO.hasCharacter(trans, username, characterName)) {
				return new CharacterResult(Result.FAILED_CHARACTER_EXISTS, characterName, template);
			}
			characterDAO.addCharacter(trans, username, characterName, template);
			transactionPool.commit(trans);
			return new CharacterResult(Result.OK_CREATED, characterName, template);
		} catch (Exception e) {
			transactionPool.rollback(trans);
			return new CharacterResult(Result.FAILED_EXCEPTION, characterName, template);
		}
	}

	@Override
	public void endTurn() {
	}

	@Override
	public void execute(RPObject caster, RPAction action) {
		
	}

	@Override
	public boolean onActionAdd(RPObject caster, RPAction action, List<RPAction> actionList) {
		return true;
	}

	@Override
	public boolean onExit(RPObject character) throws RPObjectNotFoundException {
		return false;
	}

	@Override
	public boolean onInit(RPObject character) throws RPObjectInvalidException {
		return false;
	}

	@Override
	public void onTimeout(RPObject character) throws RPObjectNotFoundException {
		onExit(character);
	}

	@Override
	public void setContext(RPServerManager rpman) {
		this.manager = rpman;
	}
}
